package com.hk.blog.service.impl;

import com.hk.blog.domain.Permission;
import com.hk.blog.repository.jpa.PermissionRepository;
import com.hk.blog.service.PermissionMenuService;
import com.hk.blog.service.PermissionService;
import com.hk.blog.vo.PermissionMenuBean;
import com.hk.commons.JsonResult;
import com.hk.commons.util.BeanUtils;
import com.hk.core.data.jpa.repository.BaseJpaRepository;
import com.hk.core.service.exception.ServiceException;
import com.hk.core.service.jpa.impl.JpaServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

@Service
@RequiredArgsConstructor
public class PermissionServiceImpl extends JpaServiceImpl<Permission, Long>
        implements PermissionService {

    private final PermissionRepository permissionRepository;

    private final PermissionMenuService permissionMenuService;

    @Override
    protected BaseJpaRepository<Permission, Long> getBaseRepository() {
        return permissionRepository;
    }

    @Override
    protected ExampleMatcher ofExampleMatcher() {
        return super.ofExampleMatcher()
                .withMatcher("permissionCode", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("permissionName", ExampleMatcher.GenericPropertyMatchers.contains());
    }

    @Override
    @Transactional
    public Permission insert(Permission permission, Function<Permission, Permission> function) {
        permission = function.apply(permission);
        if (permissionRepository.existsByPermissionCode(permission.getPermissionCode())) {
            throw new ServiceException(JsonResult.failure("该权限已存在"));
        }
        return internalSaveOrUpdate(permission);
    }

    private Permission internalSaveOrUpdate(Permission permission) {
        Permission save;
        if (permission instanceof PermissionMenuBean permissionMenuBean) {
            Permission newPerm = new Permission();
            BeanUtils.copyNotNullProperties(permissionMenuBean, newPerm);
            save = permissionRepository.save(newPerm);
            permissionMenuService.updatePermMenus(save.getId(), permissionMenuBean.getMenuIds());
        } else {
            save = permissionRepository.save(permission);
        }
        return save;
    }

    @Override
    @Transactional
    public Permission updateById(Permission permission, Function<Permission, Permission> function) {
        permission = function.apply(permission);
        Optional<Permission> optionalPermission = permissionRepository.findByPermissionCode(permission.getPermissionCode());
        if (optionalPermission.isPresent() && !Objects.equals(optionalPermission.get().getId(), permission.getId())) {
            throw new ServiceException(JsonResult.failure("该权限已存在"));
        }
        return internalSaveOrUpdate(permission);
    }
}
